// 简单数据相应

var data = { a: 1, b: { bb: 2 }, c: 3 }

function walk(data) {
  for (let key in data) {
    const dep = []
    let val = data[key]

    var nativeString = Object.prototype.toString.call(val)
    if (nativeString === '[object Object]')
      // walk(val) // <<< -----------
      arguments.callee(val)

    Object.defineProperty(data, key, {
      set: function(newVal) {
        if (newVal === val) return
        if (Object.prototype.toString.call(newVal) === '[object Object]') {
          console.log('set walk base info')
          walk(newVal)
        }
        dep.forEach(fn => fn())
        val = newVal
      },
      get: function() {
        typeof targer === 'function' && dep.push(targer)
        return val
      }
    })
  }
}
walk(data)

var targer

function $watch(data, key, fn) {
  targer = fn
  let pathArr,
    obj = data
  if (/\./.test(key)) {
    pathArr = key.split('.')
    pathArr.forEach(p => {
      obj = obj[p]
    })
    targer = ''
    return
  }
  data[key]
  targer = ''
}

$watch(data, 'c', () => {
  console.log('c_1')
})
$watch(data, 'b', () => {
  console.log('b_1')
})
$watch(data, 'b.bb', () => {
  console.log('bb_1')
})
$watch(data, 'a', () => {
  console.log('a_2')
})
$watch(data, 'a', () => {
  console.log('a_1')
})

// data.c = 1
data.a = 2
// data.b = { bb: 'b' }
data.b.bb = '1'
data.d = '3'
